package com.example.pc.videodemo

import android.media.*
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.SeekBar
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.activity_main.*
import org.java_websocket.WebSocket
import org.java_websocket.client.WebSocketClient
import java.io.ByteArrayInputStream
import java.net.URI
import kotlin.concurrent.thread
import com.example.pc.videodemo.bean.IdModel
import com.example.pc.videodemo.http.ApiService
import com.example.pc.videodemo.http.RetrofitFactory
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers


class MainActivity : AppCompatActivity() {

    private lateinit var client: WebSocketClient

    private var isGranted = false
    private var isRecording = true

    private var disposable: Disposable? = null

    private val service by lazy {
        RetrofitFactory.newInstance.create(ApiService::class.java)
    }

    private val sampleRate = 8000
    private val channelIn = AudioFormat.CHANNEL_IN_MONO
    private val channelOut = AudioFormat.CHANNEL_OUT_MONO
    private val audioFormat = AudioFormat.ENCODING_PCM_16BIT

    private val trackBufferSize by lazy { AudioTrack.getMinBufferSize(sampleRate, channelOut, audioFormat) }

    private val recordBufferSize by lazy { AudioTrack.getMinBufferSize(sampleRate, channelOut, audioFormat) }

    private val audioTrack by lazy {
        AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate,
                channelOut,
                audioFormat,
                trackBufferSize,
                AudioTrack.MODE_STREAM)
    }

    /**
     * MediaRecorder.AudioSource.MIC指的是麦克风
     */
    private val audioRecord by lazy {
        AudioRecord(MediaRecorder.AudioSource.MIC,
                sampleRate,
                channelIn,
                audioFormat,
                recordBufferSize)
    }

    private val pcm2WavUtil by lazy {
        FileUtils(sampleRate, channelIn, audioFormat)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 权限申请
        requestPermission()

        initWebSocket()

        btnReceive.setOnClickListener {
            if (client.readyState == WebSocket.READYSTATE.NOT_YET_CONNECTED) {
                client.connect()
            }

            audioTrack.play()
            service.talkIntercom(IdModel(10))
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe({
                        if (!isGranted) {
                            toast("拒绝权限申请, 录音功能无法使用")
                            return@subscribe
                        }

                        //检测AudioRecord初始化是否成功
                        if (audioRecord.state != AudioRecord.STATE_INITIALIZED) {
                            toast("录音初始化失败")
                            return@subscribe
                        }

                        audioRecord.startRecording()
                        isRecording = true

                        thread {
                            val data = ByteArray(recordBufferSize)
                            while (isRecording) {
                                val readSize = audioRecord.read(data, 0, recordBufferSize)
                                if (readSize >= AudioRecord.SUCCESS) {
                                    client.send(pcm2WavUtil.pcm2wav(data))
                                } else {
                                    "读取失败".showLog()
                                }
                            }
                        }
                    }, {
                        "error = $it".showLog()
                    })
        }

        btnHangup.setOnClickListener {
            isRecording = false
            // 关掉录音
            audioRecord.stop()
            // 关掉播放
            audioTrack.stop()

            service.hangupIntercom(IdModel(10))
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe {
                        toast("挂断成功")
                    }
        }

//        sbProgress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
//            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
//                setVolume(progress.toFloat())
//            }
//
//            override fun onStartTrackingTouch(seekBar: SeekBar?) {
//            }
//
//            override fun onStopTrackingTouch(seekBar: SeekBar?) {
//            }
//        })

//        //长按触发录音
//        btnRecorder.setOnLongClickListener {
//
//            "hello".showLog()
//
//            if (!isGranted) {
//                toast("拒绝权限申请, 录音功能无法使用")
//                return@setOnLongClickListener true
//            }
//
//            //检测AudioRecord初始化是否成功
//            if (audioRecord.state != AudioRecord.STATE_INITIALIZED) {
//                toast("录音初始化失败")
//                return@setOnLongClickListener true
//            }
//
//            toast("开始录音")
//
//            currentTime = Date().time.toString()
//
//            val file = File(getExternalFilesDir(DIRECTORY_MUSIC), "$currentTime.pcm")
//            file.createNewFile()
//
//            audioRecord.startRecording()
//            isRecording = true
//
//            thread {
//
//                val os = FileOutputStream(file)
//                val data = ByteArray(recordBufferSize)
//                while (isRecording) {
//                    val readSize = audioRecord.read(data, 0, recordBufferSize)
//                    // 如果读取音频数据没有出现错误，就将数据写入到文件
//                    if (readSize >= AudioRecord.SUCCESS) {
//                        //  TODO 写入录音文件
//
//                        // 发送录音数据给后台
//                        // client.send(data)
//                        os.write(data)
//                    } else {
//                        "读取失败".showLog()
//                    }
//                }
//            }
//            false
//        }
//
//        // 录音发送
//        btnRecorder.setOnClickListener {
//            "world".showLog()
//
//            val pcmFile = File(getExternalFilesDir(DIRECTORY_MUSIC), "$currentTime.pcm")
//            val wavFile = File(getExternalFilesDir(DIRECTORY_MUSIC), "$currentTime.wav")
//            wavFile.createNewFile()
//            pcm2WavUtil.pcmToWav(pcmFile.absolutePath, wavFile.absolutePath)
//            // 2GB 大小限制
//            client.send(wavFile.readBytes())
//
//            isRecording = false
//
//            audioRecord.stop()
//        }
    }

    private fun initWebSocket() {
        val uri = URI.create("ws://192.168.1.140:3014/websocket/16502")
        client = JWebSocketClient(uri) {
            val buffer = ByteArray(trackBufferSize)
            it?.let { byteBuffer ->
                //byteBuffer.array().size.toString().showLog()

                val inputStream = ByteArrayInputStream(byteBuffer.array())
                while (inputStream.available() > 0) {
                    val readCount = inputStream.read(buffer)
                    if (readCount == -1) {
                        "没有更多数据可以读取了".showLog()
                        break
                    }
                    audioTrack.write(buffer, 0, readCount)
                }
            }
        }
    }

    private fun requestPermission() {
        disposable = RxPermissions(this)
                .request(android.Manifest.permission.RECORD_AUDIO,
                        android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe { granted ->
                    if (!granted) {
                        toast("拒绝权限申请, 录音功能无法使用")
                        return@subscribe
                    }

                    isGranted = true
                }
    }

//    fun setVolume(value: Float) {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            audioTrack.setVolume(value)
//        } else {
//            audioTrack.setStereoVolume(value, value)
//        }
//    }

    override fun onDestroy() {
        super.onDestroy()
        client.close()
        disposable?.dispose()
        audioRecord.stop()
        audioRecord.release()
    }
}
